﻿#pragma once

#include "ais/ais_point.h"
#include "geom/geom_surface.h"
#include "topo/topo_base.h"

namespace CAGD
{

/**
 * 命令接口.
 */
class Command
{
  public:
    /**
     * @brief 默认构造.
     * @see
     */
    Command();

    /**
     * @brief 完成命令.
     * @return
     * @see
     */
    virtual CmdStatus Perform() = 0;

    /**
     * @brief 执行命令.
     * @return
     * @param c
     * @see
     */
    virtual CmdStatus Step(char c) = 0;

    /**
     * @brief 移动命令.
     * @return
     * @param c
     * @see
     */
    virtual CmdStatus Move() = 0;

  protected:
    AIS_Context &m_context;
};

/**
 * 定义宏替换为智能指针.
 * 这里 Handle(Command)(*)() 是返回 Handle(Command) 的函数
 */
using CommandFactory = GenericFactory<Command, std::string, Handle(Command) (*)()>;

/**
 * 构造命令.
 */
#define CAGD_CREATE_COMMAND(command)                                                                                   \
    static Handle(CAGD::Command) CreateCommand()                                                                       \
    {                                                                                                                  \
        return Handle(CAGD::Command)(new command);                                                                     \
    }

/**
 * 点构造类.
 */
class CmdPoint : public Command
{
  public:
    CAGD_CREATE_COMMAND(CmdPoint)

    /**
     * @brief 完成点构造.
     * @return
     * @see
     */
    virtual CmdStatus Perform() override;

    /**
     * @brief 执行一步（采点）.
     * @return
     * @param c
     * @see
     */
    virtual CmdStatus Step(char c) override;

    /**
     * @brief 移动命令（默认没有操作）.
     * @return
     * @see
     */
    virtual CmdStatus Move() override;
};

/**
 * 向量构造类.
 */
class CmdVector : public CmdPoint
{
  public:
    CAGD_CREATE_COMMAND(CmdVector)

    /**
     * @brief 执行一步（采点）.
     * @return
     * @param c
     * @see
     */
    virtual CmdStatus Step(char c) override;
};

/**
 * 曲线绘制类.
 */
class CmdCurvePainter : public CmdPoint
{
  public:
    /**
     * @brief 执行一步（采点）.
     * @return
     * @param c
     * @see
     */
    virtual CmdStatus Step(char c) override;

    /**
     * @brief 完成曲线构造.
     * @return
     * @see
     */
    virtual CmdStatus Perform() override;

  protected:
    std::vector<Handle(AIS_Point)> m_points;
};

/**
 * 基本曲线构造类.
 */
class CmdCurveBuilder : public CmdCurvePainter
{
  public:
    /**
     * @brief 完成曲线构造.
     * @return
     * @see
     */
    virtual CmdStatus Perform() override;

  protected:
    Handle(GeomCurve) m_curve;
};

/**
 * 曲面绘制类.
 */
class CmdSurfacePainter : public CmdCurvePainter
{
};

/**
 * 基本曲面构造类.
 */
class CmdSurfaceBuilder : public CmdSurfacePainter
{
  public:
    /**
     * @brief 完成曲面构造.
     * @return
     * @see
     */
    virtual CmdStatus Perform() override;

  protected:
    Handle(GeomSurface) m_surface;
};

/**
 * 拾取命令.
 */
class CmdSelector : public Command
{
  public:
    /**
     * @brief 执行一步（拾取）.
     * @return
     * @param c
     * @see
     */
    virtual CmdStatus Step(char c) override;

    /**
     * @brief 移动命令（默认没有操作）.
     * @return
     * @see
     */
    virtual CmdStatus Move() override;

    /**
     * @brief 完成.
     * @return
     * @see
     */
    virtual CmdStatus Perform() override;

  protected:
    std::vector<Handle(TopoBase)> m_objs;
};

} // namespace CAGD
